/**
 * 
 */
package furniture.render3d;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import org.eclipse.swt.graphics.RGB;

import furniture.items3d.model.tessellation.ItemSet;


/**
 * This class represent a triangle in the 3d scene.
 * @author Grill Balazs (balage.g@gmail.com)
 *
 */
public class Triangle implements Polygon3d{

	public Point3d p1;
	
	public Point3d p2;
	
	public Point3d p3;
	
	public RGB paint = new RGB(255, 0, 0);
	
	public boolean fill = true;
	
	public Triangle(){
		
	}
	
	public Triangle(Point3d p1, Point3d p2, Point3d p3){
		this.p1 = new Point3d(p1);
		this.p2 = new Point3d(p2);
		this.p3 = new Point3d(p3);
	}
	
	public Triangle(Point3d p1, Point3d p2, Point3d p3, RGB color){
		this(p1,p2,p3);
		this.fill = true;
		this.paint = color;
	}
	
	/**
	 * @return center point of triangle
	 */
	public Point3d center(){
		Point3d c = new Point3d(p1);
		c.add(p2);
		c.add(p3);
		c.scale(1.0/3.0);
		return c;
	}

	public int compareTo(Polygon3d o) {
		Double a = new Vector3d(this.center()).length();
		Double b = new Vector3d(o.center()).length();
		return a.compareTo(b);
	}
	
	public List<Point3d> getPoints(){
		List<Point3d> list = new ArrayList<Point3d>();
		list.add(p1);
		list.add(p2);
		list.add(p3);
		return list;
	}

	public boolean fill() {
		return fill;
	}

	public RGB getPaint() {
		return paint;
	}

	public void setPoints(List<Point3d> points) {
		p1 = points.get(0);
		p2 = points.get(1);
		p3 = points.get(2);
	}
	
	public Polygon3d copy() {
		Triangle t = 
			new Triangle(new Point3d(p1),new Point3d(p2),new Point3d(p3));
		t.fill = fill;
		t.paint = paint;
		return t;
	}

	public void translate(Vector3d vector) {
		p1.add(vector);
		p2.add(vector);
		p3.add(vector);
	}

	public RGB getColor() {
		return paint;
	}

	public Collection<Polygon3d> getTriangles() {
		List<Polygon3d> l = new ArrayList<Polygon3d>();
		l.add(this);
		return l;
	}
	
	/**
	 * Split triangle into smaller triangles
	 * @param level split all triangles to four parts per level
	 * @return Set of the splitted triangles
	 */
	public TriangleSet split(int level){
		if (level <= 0) return this;
		ItemSet result = new ItemSet();
		
		Point3d p12 = new Point3d((p1.x+p2.x)/2,(p1.y+p2.y)/2,(p1.z+p2.z)/2);
		Point3d p13 = new Point3d((p1.x+p3.x)/2,(p1.y+p3.y)/2,(p1.z+p3.z)/2);
		Point3d p23 = new Point3d((p3.x+p2.x)/2,(p3.y+p2.y)/2,(p3.z+p2.z)/2);
		
		Triangle t1 = new Triangle(p1,p12,p13);
		Triangle t2 = new Triangle(p12,p2,p23);
		Triangle t3 = new Triangle(p13,p23,p3);
		Triangle t4 = new Triangle(p12,p23,p13);
		
		t1.paint = paint;
		t2.paint = paint;
		t3.paint = paint;
		t4.paint = paint;
		
		TriangleSet tt1 = t1.split(level-1);
		TriangleSet tt2 = t2.split(level-1);
		TriangleSet tt3 = t3.split(level-1);
		TriangleSet tt4 = t4.split(level-1);
		
		result.addSet(tt1);
		result.addSet(tt2);
		result.addSet(tt3);
		result.addSet(tt4);
		return result;
	}
	
}
